package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"go_knowledge/test"
	"log"
	"net/http"
	"sync"
	"time"
)

var secrets = gin.H{
	"foo":    gin.H{"email": "foo@bar.com", "phone": "123433"},
	"austin": gin.H{"email": "austin@example.com", "phone": "666"},
	"lena":   gin.H{"email": "lena@guapa.com", "phone": "523443"},
}

func main() {
	//r := gin.Default()
	//
	//// Group using gin.BasicAuth() middleware
	//// gin.Accounts is a shortcut for map[string]string
	//authorized := r.Group("/admin", gin.BasicAuth(gin.Accounts{
	//	"foo":    "bar",
	//	"austin": "1234",
	//	"lena":   "hello2",
	//	"manu":   "4321",
	//}))
	//
	//// /admin/secrets endpoint
	//// hit "localhost:8080/admin/secrets
	//authorized.GET("/secrets", func(c *gin.Context) {
	//	// get user, it was set by the BasicAuth middleware
	//	user := c.MustGet(gin.AuthUserKey).(string)
	//	fmt.Print(user)
	//	if secret, ok := secrets[user]; ok {
	//		c.JSON(http.StatusOK, gin.H{"user": user, "secret": secret})
	//	} else {
	//		c.JSON(http.StatusOK, gin.H{"user": user, "secret": "NO SECRET :("})
	//	}
	//})
	//
	//// Listen and serve on 0.0.0.0:8080
	//r.Run(":8080")
	router()
}

var muxt sync.Mutex

func SayHello(say string, se time.Duration) {
	muxt.Lock()
	time.Sleep(se)
	fmt.Println(say)
	muxt.Unlock()
}
func router() {
	r := gin.New()

	// Global middleware
	// Logger middleware will write the logs to gin.DefaultWriter even if you set with GIN_MODE=release.
	// By default gin.DefaultWriter = os.Stdout
	r.Use(gin.Logger())

	// Recovery middleware recovers from any panics and writes a 500 if there was one.
	r.Use(gin.Recovery())

	// Per route middleware, you can add as many as you desire.
	r.GET("/hello", func(context *gin.Context) {
		SayHello("hello", time.Second*5)
	})

	r.GET("/hey", func(context *gin.Context) {
		SayHello("hey", time.Second)
	})

	r.GET("/he", concurrent(), func(context *gin.Context) {
		log.Println("he")
	})
	// Authorization group
	// authorized := r.Group("/", AuthRequired())
	// exactly the same as:
	authorized := r.Group("/")
	// per group middleware! in this case we use the custom created
	// AuthRequired() middleware just in the "authorized" group.
	authorized.Use(func(c *gin.Context) {
		log.Println()
	})
	{
		authorized.POST("/login", func(c *gin.Context) {
			name := c.Query("name")
			pwd := c.Query("password")

			fmt.Print(name + ":" + pwd)
		})

		// nested group
		testing := authorized.Group("testing")
		testing.GET("/analytics", func(c *gin.Context) {

		})
	}

	r.Run(":8088")
}

func concurrent() gin.HandlerFunc {
	bucket := ratelimit.NewBucket(time.Second*5, 1)
	fmt.Println(&bucket)
	return func(c *gin.Context) {
		//id, _ := c.GetQuery("uid")
		//uid, _ := strconv.ParseInt(id, 10, 64)
		//fmt.Println(uid)
		//err := q.Acquire(uid, time.Second*2)
		//if err != nil {
		//	c.AbortWithStatusJSON(http.StatusGatewayTimeout, "time out")
		//}
		//
		//defer func() {
		//	err := q.Release(uid)
		//	if err == nil {
		//		log.Println("释放成功")
		//	}
		//}()
		//fmt.Println(time.Now().Unix())
		//if ! bucket.Take(1,time.Second*2) {
		//	fmt.Println(time.Now().Unix())
		//	c.AbortWithStatusJSON(http.StatusGatewayTimeout, "time out")
		//}
		c.Next()
	}
}

func Requst(router *gin.Engine) {
	//带参数的路径
	router.GET("/user/:name", func(c *gin.Context) {
		name := c.Param("name")
		fmt.Println(name)
		c.String(http.StatusOK, name)
	})

	router.GET("/user/:name/*action", func(c *gin.Context) {
		name := c.Param("name")
		action := c.Param("action")
		message := name + " is " + action
		fmt.Println(message)
		c.String(http.StatusOK, message)
	})

	//参数在请求字符串中
	router.GET("/welcome", func(c *gin.Context) {
		//如果fristname为空，则为默认值
		fristname := c.DefaultQuery("fristname", "Guste")
		lastname := c.Query("lastname")
		message := "hello:" + fristname + lastname
		c.String(http.StatusOK, message)
	})

	//参数在表单中
	router.POST("/form_post", func(c *gin.Context) {
		message := c.PostForm("message")
		nick := c.DefaultPostForm("nick", "anonymous")

		c.JSON(200, gin.H{
			"status":  "posted",
			"message": message,
			"nick":    nick,
		})
	})

	/**
	map作为查询字符串或者表单参数,查询结构如下
	POST /post?ids[a]=1234&ids[b]=hello HTTP/1.1
	Content-Type: application/x-www-form-urlencoded
	names[first]=thinkerou&names[second]=tianou
	*/
	router.POST("/post", func(c *gin.Context) {

		ids := c.QueryMap("ids")
		names := c.PostFormMap("names")

		fmt.Println("ids: %v; names: %v", ids, names)
	})

	//上传文件
	// Set a lower memory limit for multipart forms (default is 32 MiB)
	// router.MaxMultipartMemory = 8 << 20  // 8 MiB
	router.POST("/upload", func(c *gin.Context) {
		// single file
		file, _ := c.FormFile("file")
		log.Println(file.Filename)

		// Upload the file to specific dst.
		// c.SaveUploadedFile(file, dst)

		c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
	})

	//多文件上传
	// Set a lower memory limit for multipart forms (default is 32 MiB)
	// router.MaxMultipartMemory = 8 << 20  // 8 MiB
	router.POST("/upload", func(c *gin.Context) {
		// Multipart form
		form, _ := c.MultipartForm()
		files := form.File["upload[]"]

		for _, file := range files {
			log.Println(file.Filename)

			// Upload the file to specific dst.
			// c.SaveUploadedFile(file, dst)
		}
		c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))
	})

	//路由分组
	v1 := router.Group("/v1")
	{
		v1.POST("/login", func(context *gin.Context) {})
		v1.POST("/submit", func(context *gin.Context) {})
		v1.POST("/read", func(context *gin.Context) {})
	}

}
